#include <jni.h>
#include <android_native_app_glue.h>
#include <android/log.h>
#include "../../ge_internal.h"

#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "GE_JNI", __VA_ARGS__))

ge_File* geJniOpenFd(JNIEnv* env, jobject fd, jint ofs, jint len);
extern JavaVM* vm;
extern struct android_app state;


/*
Class constructor example :
	constructor = (*env)->GetMethodID(env, class, "<init>", "(II)V");
	==> takes 2 int, returns void
*/

static bool GEImage_initialized = false;
static jclass jGEImage = (void*)NULL;
static jfieldID img_ptr_id = (void*)-1;
static jfieldID img_ptr_width = (void*)-1;
static jfieldID img_ptr_height = (void*)-1;

void GEImage_init(JNIEnv* env){
	jGEImage = (*env)->FindClass(env, "com/ssp/libge/GEImage");
	img_ptr_id = (*env)->GetFieldID(env, jGEImage, "_ptr", "I");
	img_ptr_width = (*env)->GetFieldID(env, jGEImage, "width", "I");
	img_ptr_height = (*env)->GetFieldID(env, jGEImage, "height", "I");
	GEImage_initialized = true;
}

void Java_com_ssp_libge_GEImage_Load(JNIEnv* env, jobject this, jstring jfilename, jint pref_w, jint pref_h, jint flags){
	if(!GEImage_initialized){
		GEImage_init(env);
	}

	const char* filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
	ge_Image* image = geLoadImageResizedOptions(filename, pref_w, pref_h, flags);
	(*env)->ReleaseStringUTFChars(env, jfilename, filename);

	(*env)->SetIntField(env, this, img_ptr_id, (jint)image);
	(*env)->SetIntField(env, this, img_ptr_width, (jint)image->width);
	(*env)->SetIntField(env, this, img_ptr_height, (jint)image->height);
}

void Java_com_ssp_libge_GEImage_Loadid(JNIEnv* env, jobject this, jobject jfd, jlong ofs, jlong len, jint pref_w, jint pref_h, jint flags){
	if(!GEImage_initialized){
		GEImage_init(env);
	}

	ge_File* file = geJniOpenFd(env, jfd, ofs, len);
	if(file){
		ge_Image* image = geLoadImageResizedOptions(gePathFromFile(file), pref_w, pref_h, flags);
		(*env)->SetIntField(env, this, img_ptr_id, (jint)image);
		(*env)->SetIntField(env, this, img_ptr_width, (jint)image->width);
		(*env)->SetIntField(env, this, img_ptr_height, (jint)image->height);
	}
}

void Java_com_ssp_libge_GEImage_DrawImage(JNIEnv* env, jobject this, jint x, jint y, jint z, jobject jimg, jint sx, jint sy, jint ex, jint ey, jint width, jint height, jint flags){
	if(!GEImage_initialized){
		GEImage_init(env);
	}
	
	ge_Image* img = (ge_Image*)(*env)->GetIntField(env, jimg, img_ptr_id);
	if(ex < 0){
		ex = img->width;
	}
	if(ey < 0){
		ey = img->height;
	}
	if(width < 0){
		width = img->width;
	}
	if(height < 0){
		height = img->height;
	}
	geBlitImageToImageStretched(x, y, img, sx, sy, ex, ey, width, height, (ge_Image*)(*env)->GetIntField(env, this, img_ptr_id));
}


void Java_com_ssp_libge_ge_DrawImage(JNIEnv* env, jobject this, jint x, jint y, jint z, jobject jimg, jint sx, jint sy, jint ex, jint ey, jint width, jint height, jint flags){
	if(!GEImage_initialized){
		GEImage_init(env);
	}
	
	ge_Image* img = (ge_Image*)(*env)->GetIntField(env, jimg, img_ptr_id);
	if(ex < 0){
		ex = img->width;
	}
	if(ey < 0){
		ey = img->height;
	}
	if(width < 0){
		width = img->width;
	}
	if(height < 0){
		height = img->height;
	}
	geBlitImageDepthStretched(x, y, z, img, sx, sy, ex, ey, width, height, flags);
}
